/* 
 * File:   RapidServer.cpp
 * Author: dell
 * 
 * Created on 2012年4月2日, 下午1:45
 */

#include "RapidServer.h"
#include "DefaultHttpEngine.h"
#include "ServerPid.h"

#include <evhttp/HttpServer.h>
#include <evhttp/HttpServletFactory.h>

#include <vector>

using namespace std;

namespace Rapid{
    
    RapidServer::RapidServer(ServerConfig* serverConfig, string& hdir):
        Process(false, false), 
        httpServer(NULL), httpServerEventListener(this), isDaemon(false), 
            serverConfig(serverConfig), homeDir(hdir), fileCached(serverConfig), httpEngine(NULL) {
        LOG_DEBUG("");
//        initSigev();
    }

    RapidServer::~RapidServer() {
        stop();
    }
    
    void RapidServer::stop(){
        destroyHttpEngine();
//        LOG_DEBUG("httpServer:%s", (httpServer?"true":"false"));
        if(httpServer){
//            LOG_DEBUG("httpServer exist.");
            httpServer->stop();
            httpServer->getDispatcher()->removeProcesses();
            delete httpServer;
            httpServer = NULL;
        }
        fileCached.delAllSourceFileEvstats();
    }
    
    int RapidServer::getServerPort(){
        return serverConfig->port;
    }
    
    /** 不创建子进程，在本进程中启动服务 */
    bool RapidServer::start(bool daemon, void* param){
        LOG_DEBUG("daemon:%s", (daemon?"true":"false"));
        this->isDaemon = daemon;
        if(daemon){
            return Process::start(param);
        }else{
            return startHttpServer(param);
        }
    }
    
    bool RapidServer::handle(const Event* e){
//        LOG_DEBUG("e->getType:%d", e->getType());
        //忽略所有事件
        Process::handle(e);
        return true;
    }    
    
    bool RapidServer::onProcessStartedEvent(const ProcessStartedEvent* e){
//        LOG_DEBUG("e->inChildProcess:%d, allRapidServers.size():%d", e->inChildProcess, allRapidServers.size());
        return true;
    }
    
    /** 在子进程中启动服务 */
    int RapidServer::run(void* param){
//        LOG_DEBUG("allRapidServers.size:%d", allRapidServers.size());
        
        ev::loop_ref loop = ev::get_default_loop();
        loop.post_fork();        
        
        if(!startHttpServer(param)){
            return 1;
        }

        //进入EV事件循环
        //HttpServer::loop(); 
        loop.run(0);
        
            
        return 0;
    }
    
    bool RapidServer::startHttpServer(void* param){
        LOG_DEBUG("");
        
        config.workProcessCount = serverConfig->workerCount;
        config.poolMaxHttpHandlerCount = serverConfig->poolMaxHandlerCount;
        config.idleTimeout = serverConfig->timeout;
        config.requestBufferSize = serverConfig->requestBufferSize;
        config.requestLineMaxBytes = serverConfig->requestLineMaxBytes;
        config.responseBufferSize = serverConfig->responseBufferSize;
        config.eventListener = &httpServerEventListener;

        createHttpEngine();
        if(!httpEngine){
            LOG_ERROR("create HttpEngine failure. at port %d", serverConfig->port);
            LOG_DEBUG("start failure. at port %d", serverConfig->port);
            return false;
        }

        config.handlerFactory = httpEngine->getHttpHandlerFactory();

        //配置HttpServer
        httpServer = new HttpServer(serverConfig->port, httpEngine->getHttpServletFactory(), &config);

        //启动HttpServer
        if(!httpServer->start()){
            return false;
        }

        printf("start done. at port %d\n", serverConfig->port);
        
        //将pid写入server.pid文件
        ServerPid serverPid(homeDir.c_str(), serverConfig->port);
        serverPid.append(getpid());
        
        //启动信号处理事件
//        startSigev();
        
        return true;
    }


    void RapidServer::createHttpEngine(){
        if(serverConfig->existEngineConfig){
            LOG_DEBUG(serverConfig->engineConfig.lib.c_str());
            if(!httpEngineDynamicLib.open(serverConfig->engineConfig.lib.c_str())){
                LOG_ERROR("open http engine dynamic lib failure, error:%s", httpEngineDynamicLib.getError());
                return;
            }
            HttpEngineCreate_t createMethod = (HttpEngineCreate_t)httpEngineDynamicLib.getMethod(serverConfig->engineConfig.createMethod.c_str());
            if(!createMethod){
                LOG_ERROR("create http engine failure, error:%s", httpEngineDynamicLib.getError());
                return;
            }
            httpEngine = createMethod(serverConfig, serverConfig->engineConfig.createMethodParams.c_str());
        }else{
            httpEngine = new DefaultHttpEngine(serverConfig);
        }
    }


    void RapidServer::destroyHttpEngine(){
        if(httpEngine){
            if(serverConfig->existEngineConfig){
                HttpEngineDestroy_t destroyMethod = (HttpEngineDestroy_t)httpEngineDynamicLib.getMethod(serverConfig->engineConfig.destroyMethod.c_str());
                if(!destroyMethod){
                    LOG_ERROR("destroy http engine failure, error:%s", httpEngineDynamicLib.getError());
                }else{
                    destroyMethod(httpEngine, serverConfig->engineConfig.destroyMethodParams.c_str());
                }
                
                httpEngineDynamicLib.close();
            }else{
                delete httpEngine;
                httpEngine = NULL;
            }
        }
    }

    
//    void RapidServer::notifyChildren(){
//        if(httpServer){
//            httpServer->stop();
//            Dispatcher*  dispatcher = httpServer->getDispatcher();
////            dispatcher->notifyExit();//通知所有子进程退出
////            
////            dispatcher->checkExit(); //检查所有子进程是否退出, 如果都退出了，返回true
//            
//            
//        }
//    }
    
//    void RapidServer::sigintCallback(ev::sig &ev, int revents){
//        LOG_DEBUG("");
//        //通知子进程，准备退出系统了
//        notifyChildren();
//    }
//    
//    void RapidServer::initSigev(){
//        sigint.set(SIGINT);
//        sigint.set<RapidServer, &RapidServer::sigintCallback>(this);
//    }
//    
//    void RapidServer::startSigev(){
//        if(!sigint.is_active()){
//            sigint.start();
//        }
//    }
//    
//    void RapidServer::stopSigev(){
//        if(sigint.is_active()){
//            sigint.stop();
//        }
//    }
    
}

